// Google OAuth 配置和工具函数

export interface GoogleAuthConfig {
  clientId: string
  redirectUri: string
  scope: string[]
}

export interface GoogleUser {
  id: string
  email: string
  name: string
  picture?: string
}

export class GoogleAuthUtils {
  private static config: GoogleAuthConfig = {
    clientId: import.meta.env.VITE_GOOGLE_CLIENT_ID || '',
    redirectUri: import.meta.env.VITE_GOOGLE_REDIRECT_URI || `${window.location.origin}/auth/google/callback`,
    scope: [
      'https://www.googleapis.com/auth/userinfo.profile',
      'https://www.googleapis.com/auth/userinfo.email'
    ]
  }

  /**
   * 检查Google OAuth是否已配置
   */
  static isConfigured(): boolean {
    return !!this.config.clientId
  }

  /**
   * 生成Google OAuth授权URL
   */
  static generateAuthUrl(): string {
    if (!this.isConfigured()) {
      throw new Error('Google OAuth not configured')
    }

    const params = new URLSearchParams({
      client_id: this.config.clientId,
      redirect_uri: this.config.redirectUri,
      scope: this.config.scope.join(' '),
      response_type: 'code',
      access_type: 'offline',
      prompt: 'consent'
    })

    return `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`
  }

  /**
   * 从URL中提取授权码
   */
  static extractCodeFromUrl(url: string = window.location.href): string | null {
    const urlObj = new URL(url)
    return urlObj.searchParams.get('code')
  }

  /**
   * 从URL中提取错误信息
   */
  static extractErrorFromUrl(url: string = window.location.href): string | null {
    const urlObj = new URL(url)
    return urlObj.searchParams.get('error')
  }

  /**
   * 清理URL中的OAuth参数
   */
  static cleanupUrl(): void {
    const url = new URL(window.location.href)
    url.searchParams.delete('code')
    url.searchParams.delete('state')
    url.searchParams.delete('error')
    url.searchParams.delete('error_description')
    
    window.history.replaceState({}, document.title, url.toString())
  }

  /**
   * 重定向到Google OAuth授权页面
   */
  static redirectToAuth(): void {
    if (!this.isConfigured()) {
      throw new Error('Google OAuth not configured')
    }

    const authUrl = this.generateAuthUrl()
    window.location.href = authUrl
  }

  /**
   * 在新窗口中打开Google OAuth授权页面
   */
  static openAuthPopup(): Promise<string> {
    return new Promise((resolve, reject) => {
      if (!this.isConfigured()) {
        reject(new Error('Google OAuth not configured'))
        return
      }

      const authUrl = this.generateAuthUrl()
      const popup = window.open(
        authUrl,
        'google-auth',
        'width=500,height=600,scrollbars=yes,resizable=yes'
      )

      if (!popup) {
        reject(new Error('Failed to open popup window'))
        return
      }

      // 监听popup窗口的URL变化
      const checkClosed = setInterval(() => {
        if (popup.closed) {
          clearInterval(checkClosed)
          reject(new Error('Authentication cancelled'))
          return
        }

        try {
          // 检查popup是否重定向到了回调URL
          if (popup.location.href.includes(this.config.redirectUri)) {
            const code = this.extractCodeFromUrl(popup.location.href)
            const error = this.extractErrorFromUrl(popup.location.href)

            popup.close()
            clearInterval(checkClosed)

            if (error) {
              reject(new Error(`Google OAuth error: ${error}`))
            } else if (code) {
              resolve(code)
            } else {
              reject(new Error('No authorization code received'))
            }
          }
        } catch (e) {
          // 跨域错误，继续等待
        }
      }, 1000)

      // 10分钟超时
      setTimeout(() => {
        if (!popup.closed) {
          popup.close()
        }
        clearInterval(checkClosed)
        reject(new Error('Authentication timeout'))
      }, 600000)
    })
  }

  /**
   * 使用Google Identity Services (新版本)
   */
  static async initializeGoogleIdentity(): Promise<void> {
    if (!this.isConfigured()) {
      throw new Error('Google OAuth not configured')
    }

    return new Promise((resolve, reject) => {
      // 检查是否已经加载
      if (window.google && window.google.accounts) {
        resolve()
        return
      }

      // 由于我们已经在HTML中包含了脚本，只需要等待加载完成
      const checkGoogleLoaded = () => {
        if (window.google && window.google.accounts) {
          resolve()
        } else {
          // 继续等待，最多等待10秒
          setTimeout(checkGoogleLoaded, 100)
        }
      }

      // 开始检查
      checkGoogleLoaded()

      // 设置超时
      setTimeout(() => {
        if (!window.google || !window.google.accounts) {
          reject(new Error('Google Identity Services failed to load within timeout'))
        }
      }, 10000) // 10秒超时
    })
  }

  /**
   * 使用Google Identity Services进行一键登录
   */
  static async signInWithGoogle(): Promise<string> {
    await this.initializeGoogleIdentity()

    return new Promise((resolve, reject) => {
      if (!window.google) {
        reject(new Error('Google Identity Services not loaded'))
        return
      }

      window.google.accounts.id.initialize({
        client_id: this.config.clientId,
        callback: (response: any) => {
          if (response.credential) {
            resolve(response.credential)
          } else {
            reject(new Error('No credential received from Google'))
          }
        },
        auto_select: false,
        cancel_on_tap_outside: true
      })

      window.google.accounts.id.prompt((notification: any) => {
        if (notification.isNotDisplayed() || notification.isSkippedMoment()) {
          // 如果一键登录不可用，回退到弹窗方式
          this.openAuthPopup()
            .then(code => {
              // 这里需要将code转换为ID token，或者使用不同的处理方式
              reject(new Error('Popup auth not implemented for ID token flow'))
            })
            .catch(reject)
        }
      })
    })
  }
}

// 扩展Window接口以支持Google Identity Services
declare global {
  interface Window {
    google?: {
      accounts: {
        id: {
          initialize: (config: any) => void
          prompt: (callback?: (notification: any) => void) => void
          renderButton: (element: HTMLElement, config: any) => void
        }
      }
    }
  }
}
